package tuse.components.tuseViewer
{
	import UIFree.uif_ecomponent;
	import UIFree.uif_loader;
	
	import flash.display.DisplayObject;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix3D;
	import flash.geom.Point;
	import flash.geom.Vector3D;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;
	
	import tuse.classes.ts_servers;
	import tuse.classes.ts_tuse;
	import tuse.components.ts_tuseView;

	public class ts_tuseDisplay extends uif_ecomponent {
		public var MAXDISTANCE	: Number = 1000;
		private var _actorLayer	: uif_ecomponent;
		private var _backLayer	: uif_ecomponent;
		private var _focus		: ts_actor;
		private var _tuse		: ts_tuse;
		
		public function ts_tuseDisplay(parent: ts_tuseView, ax:int=0, ay:int=0, awidth:int=0, aheight:int=0, styleClass:String='') {
			super(parent, ax, ay, awidth, aheight, styleClass);
			addEvent(MouseEvent.MOUSE_MOVE, doMove, stage);
			_backLayer 	= new uif_ecomponent(this);
			_actorLayer = new uif_ecomponent(this);
		}
		
		public function get actorLayer(): uif_ecomponent {
			return _actorLayer;
		}
		
		public function get backLayer(): uif_ecomponent {
			return _backLayer;
		}
		
		public function get view(): ts_tuseView {
			return parent as ts_tuseView;
		}
		
		public function assignTuse(a_tuse: ts_tuse): void {
			_actorLayer.removeChilds(ts_actor);
			_tuse = a_tuse;
			_tuse.partners.forEach(function(item: Object, index: int, arr: Array): void {
				var actor: ts_actor = new ts_actor(_actorLayer, item);
				
				var z: Number = item.rate / 1000 * MAXDISTANCE;
				
				var mat: Matrix3D = new Matrix3D();
				mat.appendScale(ts_actor.MODELSCALE, ts_actor.MODELSCALE, 1);
				mat.appendTranslation(0, 0, z);
				mat.appendTranslation(width * 1.6 * index / _tuse.partners.length, height - 700 * ts_actor.MODELSCALE, 0);
				actor.transform.matrix3D = mat;
			});
			
			_backLayer.disposeChilds();
			
			if (_tuse.back) {
				new uif_loader(_backLayer, ts_servers.BACKURLPATH + _tuse.back, function(e: Event): void {
					var lc: LoaderInfo = e.target as LoaderInfo;
					var backz: Number = MAXDISTANCE * 2;
					var lt: Vector3D = view.toSurface(new Vector3D(0, 0, backz), new Point(0, 0));
					var rb: Vector3D = view.toSurface(new Vector3D(0, 0, backz), new Point(width, height));
					var size: Point = new Point(rb.x - lt.x, rb.y - lt.y);
					var scalea: Point = new Point(size.x/lc.width, size.y/lc.height);
					
					var scale: Number = (scalea.x > scalea.y)?scalea.x:scalea.y;
					var mat: Matrix3D = new Matrix3D();
					mat.appendScale(scale, scale, 1);
					mat.appendTranslation(lt.x + (size.x - lc.width * scale) / 2,
											lt.y + (size.y - lc.height * scale) / 2, lt.z);
					_backLayer.transform.matrix3D = mat;
				});
			}
			
			orderZ();
		}
		
		protected function orderZ(): void {
			var depth: Array = new Array();
			var l_mc: DisplayObject;
			
			for (var i: int=0; i < actorLayer.numChildren; i++) {
				l_mc = actorLayer.getChildAt(i);
				depth.push({depth: l_mc.z, mc: l_mc});
			}
			depth.sortOn('depth', Array.NUMERIC | Array.DESCENDING);
			for (i=0;i<depth.length;i++) {
				l_mc = actorLayer.getChildAt(i);
				if (l_mc != depth[i].mc) actorLayer.swapChildren(l_mc, depth[i].mc);
			}
		}
		
		public function getHitList(p: Point): Array {
			var result: Array = new Array();
			actorLayer.forEach(function(item: Object): void {
				if (item is ts_actor) {
					if (item.hitTest(p)) result.push(item);
				}
			});
			
			result.sortOn('z', Array.NUMERIC | Array.DESCENDING);
			return result;
		}
		
		protected function get focus(): ts_actor {
			return _focus;
		}
		
		protected function set focus(a_actor: ts_actor): void {
			if (_focus != a_actor) {
				if (_focus) _focus.contur = 0;
				_focus = a_actor;
				if (_focus) {
					_focus.contur = 1;
					Mouse.cursor = MouseCursor.BUTTON;
				} else {
					Mouse.cursor = MouseCursor.ARROW;
				}
			}
		}
		
		protected function doMove(e: MouseEvent): void {
			var list: Array = getHitList(new Point(mouseX, mouseY));
			if (list.length > 0) focus = list[list.length - 1];
			else focus = null;
		} 		
	}
}